import Vue from 'vue'
import axios from 'axios'
import router from '@/router'
import qs from 'qs'
import merge from 'lodash/merge'
import {clearLoginInfo} from '@/utils'
import {Message} from "element-ui";
import {Loading} from 'element-ui';

const CryptoJS = require('crypto-js');
let loading;


const http = axios.create({
  timeout: 1000 * 30,
  withCredentials: true,
  headers: {
    'Content-Type': 'application/json; charset=utf-8'
  }
})

let loadingNum = 0;  //  内存中正在请求的数量

const constUtil = {
  DEVICEID: "deviceId",
  CHANNEL: "channel",
  RANDOM: "random",
  TIME: "time",
  VERSION: "version",
  VERSION_VALUE: "1.0.0",
  AUTHORIZATION: "token",
  KEY_VALUE: window.SITE_CONFIG.key,
  SIGN: "sign",
}

function encrypt(text) {
  return CryptoJS.MD5(text)
}



function uuid(len, radix) {
  let chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('')
  let uuid = [],
    i
  radix = radix || chars.length;
  if (len) {
    for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix]
  } else {
    let r
    uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-'
    uuid[14] = '4'
    if (!uuid[i]) {
      r = 0 | Math.random() * 16
      uuid[i] = chars[(i === 19) ? (r & 0x3) | 0x8 : r]
    }
  }
  return uuid.join('');
}

function getOrderParamsStr(params) {
  let orderParamsStr = ""
  Object.keys(params).sort().forEach(function (key) {
    if (Array.isArray(params[key]) || params[key] instanceof Object) {
      orderParamsStr += key + "=" + JSON.stringify(params[key]) + "&"
    } else {
      console.log(params[key])
      if (params[key] !== "") {
        orderParamsStr += key + "=" + params[key] + "&"
      }
    }
  })
  return orderParamsStr
}

function startLoading() {  //  打开加载动画
  if (loadingNum === 0) {
    loading = Loading.service({
      lock: true,
      text: '拼命加载中...',
      background: 'rgba(255,255,255,0.5)',
      target: document.querySelector('.el-dialog__wrapper .el-tabs__content')
    })
  }
  loadingNum++;
}

function endLoading() {  //  关闭加载动画
  loadingNum--;
  if (loadingNum <= 0) {
    loading.close();
  }
}

/**
 * 请求拦截
 */
http.interceptors.request.use(config => {
  try {
    config.headers[constUtil.AUTHORIZATION] = Vue.cookie.get(constUtil.AUTHORIZATION) // 请求头带上token
    config.headers[constUtil.DEVICEID] = window.localStorage.getItem(constUtil.DEVICEID);
    //拦截请求
    let deviceId = window.localStorage.getItem(constUtil.DEVICEID);
    let time = new Date().getTime();
    let random = uuid(32, 12)
    if (deviceId == null || deviceId === "") {
      deviceId = uuid(32, 32);
      window.localStorage.setItem(constUtil.DEVICEID, deviceId);
    }
    let params = {}
    let type = config.method
    if (type === "post" || type === "POST") {
      params = {"body": config.data}
      if (config.data) {
        params = {"body": config.data}
      }
      if (config.params) {
        params = {...params, ...config.params}
      }
    }else {
      if (config.params) {
        params = config.params;
      }
      if (config.data) {
        params = {...params, "body": config.data};
      }
   }
    config.headers[constUtil.CHANNEL] = "web"
    config.headers[constUtil.VERSION] = constUtil.VERSION_VALUE
    config.headers[constUtil.DEVICEID] = deviceId
    config.headers[constUtil.TIME] = time
    config.headers[constUtil.RANDOM] = random
    params[constUtil.CHANNEL] = "web"
    params[constUtil.VERSION] = constUtil.VERSION_VALUE
    params[constUtil.DEVICEID] = deviceId
    params[constUtil.TIME] = time
    params[constUtil.RANDOM] = random
    let orderParamsStr = getOrderParamsStr(params)
    orderParamsStr += constUtil.KEY_VALUE;
    console.log(orderParamsStr)
    config.headers[constUtil.SIGN] = encrypt(orderParamsStr)
  }catch (e) {
    console.error("设置异常",e)
  }
  startLoading();
  return config
}, error => {
  return Promise.reject(error)
})
/**
 * 响应拦截
 */
http.interceptors.response.use(response => {
  endLoading();
  if (response.data && response.data.code === 401) { // 401, token失效
    router.push({name: 'login'})
    return
  }
  if (response.data && response.data.code !== 200) { // 401, token失效
    Message.error(response.data.msg)
    return response
  }
  if (response && response.status !== 200) {
    Message.error("网络通信异常")
  }
  return response
}, error => {
  endLoading();
  if (error.response && error.response.status === 401) {
    clearLoginInfo()
    Message.error(error.response.data.msg)
    return Promise.reject(error)
  }
  if (error.response && error.response.status === 40) { //签名异常
    clearLoginInfo()
    Message.error(error.response.data.msg)
    return Promise.reject(error)
  }
  console.log(error.status);
  Message.error("网络通信异常")
  return Promise.reject(error)
})

/**
 * 请求地址处理
 * @param {*} actionName action方法名称
 */
http.adornUrl = (actionName) => {
  // 非生产环境 && 开启代理, 接口前缀统一使用[/proxyApi/]前缀做代理拦截!
  return (process.env.NODE_ENV !== 'production' && process.env.OPEN_PROXY ? '/proxyApi/' : window.SITE_CONFIG.baseUrl) + actionName
}

/**
 * get请求参数处理
 * @param {*} params 参数对象
 * @param {*} openDefaultParams 是否开启默认参数?
 */
http.adornParams = (params = {}, openDefaultParams = true) => {
  var defaults = {
    't': new Date().getTime()
  }
  return openDefaultParams ? merge(defaults, params) : params
}

/**
 * post请求数据处理
 * @param {*} data 数据对象
 * @param {*} openDefaultData 是否开启默认数据?
 * @param {*} contentType 数据格式
 *  json: 'application/json; charset=utf-8'
 *  form: 'application/x-www-form-urlencoded; charset=utf-8'
 */
http.adornData = (data = {}, openDefaultData = true, contentType = 'json') => {
  var defaults = {
    't': new Date().getTime()
  }
  data = openDefaultData ? merge(defaults, data) : data
  return contentType === 'json' ? JSON.stringify(data) : qs.stringify(data)
}

export default http
